import React from 'react';
import $ from 'jquery';
import _ from 'underscore';
import moment from 'moment';
import Datepicker from 'lib/components/datepicker.jsx';
import Slider from 'lib/components/slider.jsx';
import dispatcher from 'lib/dispatcher';
import TimeStore from 'lib/stores/time-store';

export default class TimeSlider extends React.Component{
  constructor(props){
    super(props);
    var value = TimeStore.getValue()
    this.state = _.extend({
      isOpen:false,
      isCustom:!!value.endTime
    },value,this.stateFromSelected(this.valueToSelected(value)))
    this.toggle = this.toggle.bind(this)
    this._onChange = this._onChange.bind(this)
    this.toggleCustom = this.toggleCustom.bind(this)
    this.changeValue = this.changeValue.bind(this)
    this.closeMenu = this.closeMenu.bind(this)
    this.hourChange = this.hourChange.bind(this)
    this.dayChange = this.dayChange.bind(this)
  }
  valueToSelected(value){
    if(value.endTime){
      var selectSpan = value.spanTime
        , time = value.endTime - selectSpan
        , selectDate = moment(time).startOf('day').valueOf()
        , selectHour = (time - selectDate)/3600000
      return {
        selectSpan:selectSpan,
        selectDate:selectDate,
        selectHour:selectHour
      }
    }else{
      return {}
    }
  }
  stateFromSelected(selectedMap){
    var hourOfSpanLimit = this.props.customSpanLimit/3600000
      , minDate,maxDate,selectDate,minHour,maxHour,selectHour,selectSpan,customResultText,maxSpan,minSpan;
    minDate = moment(this.props.minTime).startOf('day').valueOf()
    maxDate = moment(this.props.maxTime).startOf('day').valueOf()
    if(!_.isEmpty(selectedMap)){
      // isCustom = true
      selectDate = selectedMap.selectDate
      maxHour = selectDate < maxDate ? 23 : moment(this.props.maxTime).hour() - hourOfSpanLimit
      minHour = selectDate > minDate ? 0 : moment(this.props.minTime).hour()
      selectHour = minHour === 0?Math.min(selectedMap.selectHour,maxHour):Math.max(selectedMap.selectHour,minHour)
      maxSpan = this.props.maxTime - this.resolveDateHour(selectDate,selectHour)
      minSpan = this.props.intervalSizeFn?this.props.intervalSizeFn(maxSpan):this.props.customSpanLimit
      selectSpan = Math.max(Math.min(selectedMap.selectSpan,maxSpan),minSpan)
    }else{
      // isCustom = false
      selectDate = maxDate
      maxHour = moment(this.props.maxTime).hour() - hourOfSpanLimit
      minHour = 0
      selectHour = maxHour
      maxSpan = this.props.maxTime - this.resolveDateHour(selectDate,selectHour)
      minSpan = this.props.customSpanLimit
      selectSpan = this.props.customSpanLimit
    }
    customResultText = this.resolveCustomText({
      spanTime:selectSpan,
      endTime:this.resolveDateHour(selectDate,selectHour) + selectSpan
    })
    return {
      minDate:minDate,
      maxDate:maxDate,
      selectDate:selectDate,
      minHour:minHour,
      maxHour:maxHour,
      selectHour:selectHour,
      minSpan:minSpan,
      maxSpan:maxSpan,
      selectSpan:selectSpan,
      customResultText:customResultText
    }
  }
  resolveCustomText(value){
    return [
    moment(value.endTime - value.spanTime).format('YYYY-MM-DD HH:mm'),
    moment(value.endTime).format('YYYY-MM-DD HH:mm')
    ]
  }
  resolveDateHour(date,hour){
    return date + hour*60*60*1000
  }
  closeMenu(e){
    var el = e.target
      , container = this.refs.root
    if(this.state.isOpen&&!$.contains(container,el)){
      this.setState({
        isOpen:false
      })
    }
  }
  toggle(){
    this.setState({
      isOpen:!this.state.isOpen
    })
  }
  selectItem(value){
    dispatcher.dispatch({
      $type:'SETTIME',
      data:{
        spanTime:value,
        endTime:null
      }
    });
  }
  changeValue(){
    var spanLen = TimeStore.getConfig().items.filter(
      (i) => i.value >= this.state.minSpan
    , this).filter(
      (i) => i.value <= this.state.maxSpan
    ).length
    if(spanLen){
      this.toggle()
      dispatcher.dispatch({
        $type:'SETTIME',
        data:{
          spanTime:this.state.selectSpan,
          endTime:this.resolveDateHour(this.state.selectDate,this.state.selectHour) + this.state.selectSpan
        }
      });
    }
  }
  componentDidMount(){
    TimeStore.addChangeListener(this._onChange);
    $('body').on('click',this.closeMenu)
  }
  componentWillUnmount(){
    TimeStore.removeChangeListener(this._onChange);
    $('body').off('click',this.closeMenu)
  }
  _onChange(){
    var value = TimeStore.getValue()
    this.setState(_.extend({
      isCustom:!!value.endTime
    },value,this.stateFromSelected(this.valueToSelected(value))));
    this.props.onChange(value);
  }
  getText(){
    var _this = this
    var value = TimeStore.getValue()
    var findedItem = _(TimeStore.getConfig().items).find((i) => i.value === value.spanTime,this);
    if(!findedItem){
      throw new Error('Can\'t find item in TimeStore config')
    }
    return (
      value.endTime?(
        this.resolveCustomText(value).join('至')
      ):(
        ' 最新'+findedItem.text.join('')
      )
    )
  }
  getSlotValue(){
    return parseInt($(this.refs.slot).val())
  }
  toggleCustom(){
    this.setState({
      isCustom:true
    })
  }
  hourChange(num){
    var span = this.getSlotValue()
    this.setState(this.stateFromSelected(this.valueToSelected({
      spanTime:span,
      endTime:this.resolveDateHour(this.state.selectDate,num)+span
    })))
  }
  dayChange(date) {
    var span = this.getSlotValue()
    this.setState(this.stateFromSelected(this.valueToSelected({
      spanTime:span,
      endTime:this.resolveDateHour(date,this.state.selectHour)+span
    })))
  }
  timeslot() {
    var span = this.getSlotValue()
    this.setState(this.stateFromSelected(this.valueToSelected({
      spanTime:span,
      endTime:this.resolveDateHour(this.state.selectDate,this.state.selectHour)+span
    })))
  }
  renderCustomBody(){
    return (
      <div style={{minWidth:'610px'}}>
        <div className="timepicker-main">
          <div className="timepicker-diy">
            <div className="wrapper">
              <div style={{paddingBottom:'20px'}}>
                <div style={{marginBottom:'20px'}}>
                {
                  '请选择 '+moment(this.state.selectDate).format('YYYY-MM-DD') +
                  ' 的起始时间：' +
                  moment(this.state.selectDate).add(moment.duration(this.state.selectHour,'hours')).format('HH:mm')
                }
                </div>
                <Slider
                  value={this.state.selectHour}
                  min={this.state.minHour||0}
                  max={this.state.maxHour||23}
                  orientation='horizontal'
                  onChange={this.hourChange}
                />
              </div>
            </div>
            <div className="wrapper">
              <div style={{paddingBottom:'20px'}}>
                <span>
                {
                  '请选择 '+moment(this.state.selectDate).format('YYYY-MM-DD') +
                  ' ' + moment(this.state.selectDate).add(moment.duration(this.state.selectHour,'hours')).format('HH:mm')
                   + ' '+' 向后的时间跨度：'
                }
                </span>
                <select style={{color:'#555',marginTop:'10px'}} className="select select-white" onChange={this.timeslot.bind(this)} ref="slot" value={this.state.selectSpan}>
                  {
                    TimeStore.getConfig().items.filter(
                      (i) => i.value >= this.state.minSpan
                    , this).filter(
                      (i) => i.value <= this.state.maxSpan
                    ).map(
                      (i) => (
                        <option key={i.value} value={i.value}>
                          {i.text[0]+i.text[1]}
                        </option>
                      )
                      , this)
                  }
                </select>
              </div>
          </div>
          </div>
          <Datepicker
            minDate={this.state.minDate}
            maxDate={this.state.maxDate}
            defaultValue={this.state.selectDate}
            onAfterChange={this.dayChange}
          />
        </div>
        <div className="timepicker-footer">
          <span>{'查询 '+this.state.customResultText[0]+' 至 '+this.state.customResultText[1]+' 内的性能数据'}</span>
          <button className="btn-green" type="button" onClick={this.changeValue}>确定</button>
        </div>
      </div>
    )
  }
  renderBody(){
    return (
      <div className="timepicker-dropdown-main">
        <ul>
          {
            TimeStore.getConfig().items.map(function(item){
              return (
                <li
                  key={item.value}
                  onClick={this.selectItem.bind(this,item.value)}
                  className={!this.state.isCustom&&item.value===this.state.spanTime?'active':''}
                >
                {item.text[0]+item.text[1]}
                </li>
                )
            },this)
          }
          <li onClick={this.toggleCustom} className={this.state.isCustom?'active':''}>自定义</li>
        </ul>
        {this.state.isCustom?this.renderCustomBody():null}
      </div>
    )
  }
  render(){
    return (
      <div className="dropdown time-slider" ref="root">
        <strong onClick={this.toggle}>
          <i className="iconfont icon-clock"></i>
          {
            this.getText()
          }
          <i className="iconfont icon-btn-arrow">&#xe619;</i>
        </strong>
        {this.state.isOpen?this.renderBody():null}
      </div>
    )
  }
}
var config = TimeStore.getConfig()
TimeSlider.defaultProps = {
  onChange:function(){},
  customSpanLimit:30*60*1000,
  maxTime:moment(config.maxTime).startOf('hour').valueOf(),
  minTime:moment(config.minTime).startOf('hour').valueOf()
}
